<template>
    <div class="single-form">
        <page-region
            v-for="(region, index) in submitFormFrame"
            :key="index"
            :page-region-data="submitFormData[getKey(region, index)]"
            :page-region-frame="region"
        >
            <template #pageRegionFrame-form="{ pageRegionFrame, pageRegionData }">
                <el-form
                    v-if="pageRegionFrame.type == 'form'"
                    ref="submitForm"
                    :model="pageRegionData"
                    :label-width="labelWidth"
                    :rules="rules[getKey(pageRegionFrame, index)]"
                    label-position="right"
                    size="small"
                    :class="{ 'inline-single-form': pageRegionFrame.inline }"
                    :inline="pageRegionFrame.inline"
                >
                    <template v-if="pageRegionFrame.inline == true">
                        <el-row v-for="(row, index) in pageRegionFrame.items" :key="index">
                            <el-col v-for="(item, rowIndex) in row" :key="rowIndex" :span="24 / row.length">
                                <el-form-item
                                    v-show="item.visible != false"
                                    :label="item.label + (!item.frameType || item.frameType == '' ? '：' : '')"
                                    :prop="item.key"
                                    :class="{ 'text-column': !item.frameType || item.frameType == '' }"
                                >
                                    <cell-render :cell-render-frame="item" :cell-render-data="pageRegionData">
                                        <template v-for="(scopedIndex, name) in $scopedSlots" #[name]="data">
                                            <slot :name="name" v-bind="data"></slot>
                                        </template>
                                    </cell-render>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </template>
                    <template v-else>
                        <el-form-item
                            v-for="(item, index) in pageRegionFrame.items"
                            v-show="item.visible != false"
                            :key="index"
                            :label="item.label"
                            :prop="item.key"
                        >
                            <cell-render :cell-render-frame="item" :cell-render-data="pageRegionData">
                                <template v-for="(scopedIndex, name) in $scopedSlots" #[name]="data">
                                    <slot :name="name" v-bind="data"></slot>
                                </template>
                            </cell-render>
                        </el-form-item>
                    </template>
                </el-form>
            </template>
        </page-region>

        <div style="text-align: right; margin-bottom: 10px">
            <el-button size="mini" @click="cancelFun(Object.assign({}, submitFormData))">
                {{ cancelButtonName }}
            </el-button>
            <el-button type="primary" :loading="submitLoading" size="mini" @click="submit">
                {{ submitButtonName }}
            </el-button>
        </div>
    </div>
</template>
<script>
import CellRender from '@/components/Page/CellRender.vue'
import PageRegion from '@/components/Page/PageRegion.vue'
export default {
    components: {
        CellRender,
        PageRegion
    },
    provide() {
        return { elform: () => this }
    },
    props: {
        submitButtonName: {
            type: String,
            default: '保存'
        },
        submitFun: Function,
        cancelButtonName: {
            type: String,
            default: '取消'
        },
        cancelFun: {
            type: Function,
            default: () => {}
        },
        labelWidth: {
            type: String,
            default: '80px'
        },
        submitFormFrame: {
            type: Array,
            default: () => {
                return []
            }
        },
        submitFormData: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            submitLoading: false
        }
    },
    computed: {
        rules: function () {
            let desRules = {}
            this.submitFormFrame
                .filter((v) => !v.type || v.type == 'form')
                .forEach((region, index) => {
                    var tempRule = {}
                    region.items.flat(2).forEach((v) => {
                        let validations = v.validations
                        if (validations) {
                            if (validations instanceof Array) {
                                tempRule[v.key] = validations
                            } else if (validations instanceof Object) {
                                buildValidationRule(validations, tempRule, v)
                            }
                        }
                        //特殊处理级联选择器
                        if (v.frameType == 'dynamicCascader') {
                            let rules = tempRule[v.key]
                            let index = rules.findIndex((r) => r.hasOwnProperty('required') && r.required)
                            if (index > -1) {
                                let requireRule = rules[index]
                                rules.push({
                                    trigger: 'change',
                                    validator(rule, value, callback) {
                                        let error = new Error(
                                            requireRule.message ? requireRule.message : `请选择${v.label}`
                                        )
                                        if (!value || value.every((val) => val == null)) {
                                            return callback(error)
                                        }
                                        callback()
                                    }
                                })
                                rules.splice(index, 1)
                            }
                        }
                    })
                    desRules[this.getKey(region, index)] = tempRule
                })
            return desRules
        }
    },
    created() {
        //form赋初值
        this.submitFormFrame.forEach((region, index) => {
            if (!region.type) {
                region.type = 'form'
            }
            let key = this.getKey(region, index)
            if (!this.submitFormData.hasOwnProperty(key)) {
                this.$set(this.submitFormData, key, {})
            }
            if (region.type == 'form') {
                region.items
                    .flat(2)
                    .filter((v) => !this.submitFormData[key][v.key])
                    .forEach((v) => {
                        if (v.frameType == 'upload') {
                            this.$set(this.submitFormData[key], v.key, [])
                        } else {
                            this.$set(this.submitFormData[key], v.key, null)
                        }
                    })
            }
        })
    },
    methods: {
        submit() {
            Promise.all(this.$refs.submitForm.map((v) => v.validate()))
                .then(() => {
                    this.submitLoading = true
                    let objs = new Array()
                    for (let key in this.submitFormData) {
                        objs.push(this.submitFormData[key])
                    }
                    let params = Object.assign({}, ...objs)
                    return this.submitFun(params)
                })
                .catch((err) => {})
                .finally(() => {
                    this.submitLoading = false
                })
        },
        clear() {
            this.$refs.submitForm.forEach((v) => v.resetFields())
        },
        getKey(item, index) {
            return item.key || `region${index}`
        },
        validateField(key) {
            let index = this.submitFormFrame
                .filter((v) => v.type == 'form')
                .findIndex((v) => v.items.flat(2).findIndex((item) => item.key == key) > -1)
            if (index > -1) {
                this.$refs.submitForm[index].validateField(key)
            }
        }
    }
}
function buildValidationRule(validations, rules, item) {
    let rule = new Array()
    for (let key in validations) {
        if (key == 'required') {
            let msg = validations.required
            rule.push({
                required: msg != false,
                message:
                    typeof msg == 'string' ? msg : `${item.frameType == 'input' ? '请输入' : '请选择'}${item.label}`,
                trigger: item.frameType == 'input' ? 'blur' : 'change'
            })
        }
        if (key == 'max') {
            rule.push({
                max: validations[key],
                message: `${item.label}不能超过${validations[key]}个字符`,
                trigger: item.frameType == 'input' ? 'blur' : 'change'
            })
        }
    }
    rules[item.key] = rule
}
</script>
<style lang="scss">
.single-form {
    .el-descriptions {
        padding: 0;
        margin: 0;
    }
    .text-column {
        .el-form-item__label {
            padding: 0px;
        }
    }
}
.inline-single-form {
    .el-input__inner {
        width: 220px;
    }
}
</style>
